#include <types.h>
#include <sys_config.h>
#include <osal/osal.h>
#include <hld/hld_dev.h>
#include <api/libc/string.h>
#ifdef MP4_CONTAINER
#include <hld/snd/snd_dev.h>
#include <api/libmp/pe.h>
#include "av_player/av_player.h"
P_HANDLE g_mp4_av_player_handle = 0;

//from dec_ctrl.c
enum av_player_direction g_mp4_player_direction;
enum av_player_speed g_mp4_player_speed;
//#define AVP_PE_CACHE_TEST
//From video engine.c
#define AVP_FIRST_CACHE_READ_SIZE       0xd0000
#define AVPFILE_CACHE_BLK_SIZE      0x20000
#define MP4_CACHE_SIZE			8*1024*1024//0x120000
#define MP4_CACHE_BLK_SIZE      0x20000
static UINT32 m_mp4_cache_buffer;
static BOOL m_avpFirstCacheRead = TRUE;
F_HANDLE m_mp4_test_file = 0;
int avp_cache_id = 0;
extern BOOL g_VideoDecRunning;

static DWORD avp_DecoderReadData(BYTE *buf, DWORD size)
{
    if(m_avpFirstCacheRead == TRUE)
    {
        m_avpFirstCacheRead = FALSE;
        return pe_cache_read(avp_cache_id, buf, size, AVP_FIRST_CACHE_READ_SIZE);
    }
    else
    {
        return pe_cache_read(avp_cache_id, buf, size, size);
    }
	//mpg_cache_id need to  change
}
static BOOL avp_DecoderSeekData(long long offset, DWORD origin)
{
	//mpg_cache_id need to  change
    if(!pe_cache_seek(avp_cache_id, offset, origin))
    {
        return TRUE;
    }
    else 
        return FALSE;
}
static int avp_mp4_fread(F_HANDLE file, void *buf, int size)
{
	return avp_DecoderReadData(buf, size);	
}

static long long avp_mp4_fseek(F_HANDLE file,long long offset, int flag)
{
	if(avp_DecoderSeekData(offset, flag))
		return 0;
	else
		return -1;

}

static long long avp_mp4_ftell(F_HANDLE file)
{
	return 0;
}	

void t2AvpDec_Task(UINT32 para1, UINT32 para2)
{
/*
    DEC_INIT_PAR m_DecInitPar;
    DEC_STREAM_INFO DecStreamInfo;
    struct vdec_io_reg_callback_para tpara;
    UINT8 video_stream_type = (para2 >>16)&0xff;
    enum SndDupChannel audio_channel = (para2 >>8)&0xff;
    UINT8 preview = para2&0xff;
*/
    g_VideoDecRunning = TRUE;

    m_avpFirstCacheRead = TRUE;
    PEStreamStart();

	av_player_file file;

	MEMSET((void *)&file, 0, sizeof(av_player_file));
	file.f_p = m_mp4_test_file;
	file.fread = avp_mp4_fread;
	file.fseek = avp_mp4_fseek;
	file.ftell = avp_mp4_ftell;
	av_player_play(g_mp4_av_player_handle, &file, para1);
}

//from dec_ctrl.c
DWORD avp_cmd_play_proc()
{
	g_mp4_player_direction = AV_PLAYER_FORWARD;		
	g_mp4_player_speed = AV_PLAYER_SPEEDX1;
	av_player_mode(g_mp4_av_player_handle, g_mp4_player_direction, g_mp4_player_speed);	
	av_player_resume(g_mp4_av_player_handle);
	return 1;
}
DWORD avp_cmd_pause_proc()
{
	av_player_pause(g_mp4_av_player_handle);
	g_mp4_player_direction = AV_PLAYER_FORWARD;		
	g_mp4_player_speed = AV_PLAYER_SPEED_STEP;	
	return 1;
}
DWORD avp_cmd_resume_proc()
{
	g_mp4_player_direction = AV_PLAYER_FORWARD;		
	g_mp4_player_speed = AV_PLAYER_SPEED_STEP;
	av_player_mode(g_mp4_av_player_handle, g_mp4_player_direction, g_mp4_player_speed);		
	av_player_resume(g_mp4_av_player_handle);	
	return 1;	
}

DWORD avp_cmd_ff_proc()
{
	if(AV_PLAYER_FORWARD == g_mp4_player_direction)
	{
		g_mp4_player_speed++;
		if(g_mp4_player_speed > AV_PLAYER_SPEEDX16)
			g_mp4_player_speed = AV_PLAYER_SPEEDX1;
	}
	else
		g_mp4_player_speed = AV_PLAYER_SPEEDX1;

	g_mp4_player_direction = AV_PLAYER_FORWARD;	
	av_player_mode(g_mp4_av_player_handle, g_mp4_player_direction, g_mp4_player_speed);
	return 1;
}

DWORD avp_cmd_fb_proc()
{
	if(AV_PLAYER_BACKWARD == g_mp4_player_direction)
	{
		g_mp4_player_speed++;
		if(g_mp4_player_speed > AV_PLAYER_SPEEDX16)
			g_mp4_player_speed = AV_PLAYER_SPEEDX1;
	}
	else
		g_mp4_player_speed = AV_PLAYER_SPEEDX1;	

	g_mp4_player_direction = AV_PLAYER_BACKWARD;
		
	av_player_mode(g_mp4_av_player_handle, g_mp4_player_direction, g_mp4_player_speed);
	return 1;
}

DWORD avp_cmd_slow_proc()
{
	if(AV_PLAYER_FORWARD == g_mp4_player_direction)
	{
		g_mp4_player_speed++;
		if(g_mp4_player_speed > AV_PLAYER_SPEED_1_16)
			g_mp4_player_speed = AV_PLAYER_SPEED_1_2;
		else if(g_mp4_player_speed < AV_PLAYER_SPEED_1_2)
			g_mp4_player_speed = AV_PLAYER_SPEED_1_2;
	}
	else
		g_mp4_player_speed = AV_PLAYER_SPEED_1_2;	

	g_mp4_player_direction = AV_PLAYER_FORWARD;
	
	av_player_mode(g_mp4_av_player_handle, g_mp4_player_direction, g_mp4_player_speed);

	return 1;
}


DWORD avp_cmd_stop_proc()
{
	//if(0 == m_mp4_test_file)
		//return 1;	
	av_player_stop(g_mp4_av_player_handle);
	vpo_win_onoff((struct vpo_device *)dev_get_by_type(NULL, HLD_DEV_TYPE_DIS),FALSE);
	g_VideoDecRunning = FALSE;
	//fclose(m_mp4_test_file);
	//m_mp4_test_file = 0;	
	if(avp_cache_id!=-1)
	    	pe_cache_close(avp_cache_id);		
	return 1;	
}


DWORD avp_cmd_terminate_proc()
{
	//if(0 == m_mp4_test_file)
		//return 1;	
	av_player_stop(g_mp4_av_player_handle);
	//vpo_win_onoff((struct vpo_device *)dev_get_by_type(NULL, HLD_DEV_TYPE_DIS),FALSE);
	g_VideoDecRunning = FALSE;
	//fclose(m_mp4_test_file);
	//m_mp4_test_file = 0;	
	if(avp_cache_id!=-1)
	    	pe_cache_close(avp_cache_id);		
	return 1;	
}

DWORD avp_cmd_search_proc(DWORD search_time)
{
	av_player_seek(g_mp4_av_player_handle, search_time);
	return 1;
}
//from plugin_mpeg.c
DWORD AVPFileDecoderGetPlayTime()
{
	UINT32 time = 0;

	av_player_control(g_mp4_av_player_handle, AV_PLAYER_CMD_CURRENT_TIME, &time);
	
	return time;
}

DWORD AVPGetTotalPlayTime()
{
	UINT32 time = 0;
	av_player_control(g_mp4_av_player_handle, AV_PLAYER_CMD_TOTAL_DURATION, &time);
	return time;

}
//move from video engine, mp4's architecture don't use video engine
void avp_cache_init(UINT32 cache_buf)
{
	m_mp4_cache_buffer = cache_buf;
}

int mp4_net_dec_file(char *path, BOOL preview)
{
	UINT8 * cache_buf = NULL;//(UINT8 *)(m_cache_buffer);
	UINT32 para1 = NULL;//MP4 don't support callback function
	UINT32 para2 = ((MPEG_12_FILE_STREAM<<16)|(SND_DUP_NONE<<8)|preview);
	avp_cache_id =pe_cache_open(path, (UINT8 *)m_mp4_cache_buffer, MP4_CACHE_SIZE, MP4_CACHE_BLK_SIZE);
	if(avp_cache_id == -1)
	{
	    libc_printf("mp4_net_dec_file create pe cache failed\n");
	   return -1;
	}
	t2AvpDec_Task(para1, para2);
}

#endif



